#pragma once

#include "gl.hpp"
#include <vector>

class VertexBuffer
{
public:
	VertexBuffer(unsigned int type = GL_ARRAY_BUFFER);
	VertexBuffer(const VertexBuffer&) = delete;
	VertexBuffer& operator= (const VertexBuffer&) = delete;
	~VertexBuffer();

	template<typename tVertexFormat> void SetData(std::vector<tVertexFormat>& data);
	/// Use the MEMBER_INFO define as helper here
	/** stride is the size of the struct, offset is the distance from the start of the struct, size is the number of floats**/
	void SetLocation(unsigned int location, unsigned int offset, unsigned int size, unsigned int stride);

	void Draw(unsigned int primitiveType = GL_TRIANGLES);

	unsigned int GetVertexArray() { return m_VertexArray; }
	unsigned int GetBuffer() { return m_Buffer; }
private:

	const unsigned int m_Type;
	unsigned int m_Buffer = 0;
	unsigned int m_VertexArray = 0;
	unsigned int m_NumVertices = 0;
};

//computes the offset, the size (number of floats) and the stride of an entry
#define VERTEX_BUFFER_MEMBER(tStruct, member) offsetof(tStruct, member), sizeof(tStruct().member)/4, sizeof(tStruct)

template<typename tVertexFormat> void VertexBuffer::SetData(std::vector<tVertexFormat>& data)
{
	glBindVertexArray(m_VertexArray);
	glBindBuffer(m_Type, m_Buffer);
	glBufferData(m_Type, sizeof(tVertexFormat)*data.size(), data.data(), GL_STATIC_DRAW);
	m_NumVertices = data.size();
}
